﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using UC_Framework;

namespace SwarmPlay
{
    /// <summary>
    /// helper class for global constants such as directory 
    /// </summary>
    //class Dir
    //{
    //    public static string dir = @"C:\GPT2011_Swarm_AI_Ass_XNA3\Sprite\AirDef\";
    //}

    class GameLevel_0 : UC_LevelParent
    {

        public override void LoadContent()
        {
            font1 = Content.Load<SpriteFont>("Fontey");
        }

        public override void Update(GameTime gameTime)
        {
            prevKeyState = keyState;
            keyState = Keyboard.GetState();
            if (keyState.IsKeyDown(Keys.D1) && !prevKeyState.IsKeyDown(Keys.D1))
            {
                levelManager.setLevel(1);
            }
            if (keyState.IsKeyDown(Keys.D2) && !prevKeyState.IsKeyDown(Keys.D2))
            {
                levelManager.setLevel(2);
            }
            if (keyState.IsKeyDown(Keys.D3) && !prevKeyState.IsKeyDown(Keys.D3))
            {
                levelManager.setLevel(3);
            }
            if (keyState.IsKeyDown(Keys.D4) && !prevKeyState.IsKeyDown(Keys.D4))
            {
                levelManager.setLevel(4);
            }
        }

        public override void Draw(GameTime gameTime)
        {
            gd.Clear(Color.Aqua);
            spriteBatch.Begin();
            spriteBatch.DrawString(font1, "level 0 - press 1 to go to swarm 1", new Vector2(100, 100), Color.Brown);
            spriteBatch.DrawString(font1, "level 0 - press 2 to go to swarm 2", new Vector2(100, 120), Color.Brown);
            spriteBatch.DrawString(font1, "level 0 - press 3 to go to swarm 3", new Vector2(100, 140), Color.Brown);
            spriteBatch.End();
        }
    }

    class GameLevel_1 : UC_LevelParent
    {
        public Texture2D tex1;
        public Texture2D tex2;
        public Random random;
        public Sprite2 s; //
        public SpriteList sl;

        public int numSprites = 50;
        public Vector2 swarmCenter;
        public Vector2 swarmTarget;
        public float swarmRadius;
        public float swarmSpeed;
        public int ticks = 0;

        public Rectangle[] obstacles;

        public GameLevel_1()
        {
            obstacles = new Rectangle[1]
            {
                new Rectangle(350, 250, 90, 90)
            };
        }

        public override void LoadContent()
        {
            random = new Random();

            font1 = Content.Load<SpriteFont>("Fontey");
            tex1 = Content.Load<Texture2D>("Bug2");
            tex2 = Content.Load<Texture2D>("Bee2");

            //tex1 = Game1.fromFile(Dir.dir + "Bug2.png",gd); ; // Green Guyfont1 = Content.Load<SpriteFont>("Fontey");
            //tex2 = Game1.fromFile(Dir.dir + "Bee2.png",gd); ; // Green Guyfont1 = Content.Load<SpriteFont>("Fontey");
            sl = new SpriteList(500);

            for (int i = 0; i < numSprites; i++)
            {
                s = new Sprite2(true, tex2, "bug", random.Next((int)799), random.Next((int)799), 0);
                s.setWidthHeight(32, 32);
                s.setHSoffset(new Vector2(16, 16));
                //s.setBBToWH();
                s.setDisplayAngleOffset((float)(Math.PI / 2));
                //s.setDeltaSpeed(new Vector2((float)(0.5f + randomClass.NextDouble()), 0));
                sl.addSprite(s);
            }

            swarmCenter.X = 400;
            swarmCenter.Y = 300;

            swarmTarget.X = 400;
            swarmTarget.Y = 300;

            swarmRadius = 60;
            swarmSpeed = 0.6f;

        }

        public override void Update(GameTime gameTime)
        {
            ticks++;
            getKeyboardAndMouse();

            if (keyState.IsKeyDown(Keys.N) && !prevKeyState.IsKeyDown(Keys.N))
            {
                levelManager.setLevel(2);
            }


            if (keyState.IsKeyDown(Keys.P) && !prevKeyState.IsKeyDown(Keys.P))
            {
                levelManager.pushLevel(3);
            }
            if (keyState.IsKeyDown(Keys.R) && !prevKeyState.IsKeyDown(Keys.R))
            {
            }

            if (currentMouseState.LeftButton == ButtonState.Pressed &&
                previousMouseState.LeftButton != ButtonState.Pressed)
            {
                swarmTarget.X = mouse_x;
                swarmTarget.Y = mouse_y;
            }

            moveTheSwarm();
        }

        public override void Draw(GameTime gameTime)
        {
            gd.Clear(Color.Silver);
            spriteBatch.Begin();
            //s.draw(spriteBatch);
            LineBatch.drawFillRectangleBorder(spriteBatch, obstacles[0], Color.YellowGreen, 2);
            sl.drawAll(spriteBatch);


            LineBatch.drawCross(spriteBatch, mouse_x, mouse_y, 4, Color.Black, Color.Black);
            LineBatch.drawCrossX(spriteBatch, swarmCenter.X, swarmCenter.Y, 4, Color.Brown, Color.Brown);
            LineBatch.drawCrossX(spriteBatch, swarmTarget.X, swarmTarget.Y, 4, Color.Gray, Color.Gray);

            LineBatch.drawCircle(spriteBatch, Color.Bisque, new Vector2(swarmCenter.X, swarmCenter.Y), swarmRadius, 30, 1);

            // sl.drawInfo(spriteBatch, Color.Black, Color.White); // comment in to see bounding boxes

            spriteBatch.End();
        }

        void moveTheSwarm()
        {
            // move swarm center
            float angleBase = Util.getAngle(swarmTarget, swarmCenter);
            Vector2 t = Util.moveByAngleDist(swarmCenter, angleBase, swarmSpeed);
            swarmCenter.X = t.X;
            swarmCenter.Y = t.Y;
            float delta = (float)(Math.PI / 180.0 * 2);

            for (int i = 0; i < numSprites; i++)
            {
                Sprite2 s = sl.getSprite(i);
                if (s == null) continue;
                float angle = angleBase + ((random.Next(200) - 100) / 200.0f);
                // is it in swarm radius
                if ((s.getPos() - swarmCenter).Length() < swarmRadius)
                {
                    float a = s.getMoveAngle(); // +(float)(2 * Math.PI);
                    if (Math.Abs(a - angle) > Math.PI)
                    {
                        if (a < angle) a = a - delta;
                        if (a > angle) a = a + delta;
                    }
                    else
                    {
                        if (a < angle) a = a + delta;
                        if (a > angle) a = a - delta;
                    }
                    if (a < -2 * Math.PI) a = a + (float)Math.PI * 2;
                    if (a > 2 * Math.PI) a = a - (float)Math.PI * 2;
                    s.setMoveAngle(a);
                    s.setDisplayAngle(a);
                    if (ticks % 10 == 0)
                    {
                        //a = a + ((random.Next(200) - 10) / 500.0f);
                        s.setMoveAngle(a);
                        s.setDisplayAngle(a);
                        s.setMoveSpeed(swarmSpeed + (random.Next(10) / 10.0f));
                    }
                    s.moveByAngleSpeed(true);
                    s.setColor(Color.HotPink);

                }
                else
                {
                    //s.moveTo(swarmCenter, 1, true, true);
                    float newAngle = Util.getAngle(swarmCenter, s.getPos());
                    float a = s.getMoveAngle(); // +(float)(2 * Math.PI);
                    float olda = a;
                    if (Math.Abs(a - newAngle) > Math.PI)
                    {
                        if (a < newAngle) { a = a - delta; s.setColor(Color.Blue); }
                        if (a > newAngle) { a = a + delta; s.setColor(Color.Gray); }

                    }
                    else
                    {
                        if (a < newAngle) { a = a + delta; s.setColor(Color.Green); }
                        if (a > newAngle) { a = a - delta; s.setColor(Color.Orange); }
                        //s.setColor(Color.Green);
                    }
                    if (a < -2 * Math.PI) a = a + (float)Math.PI * 2;
                    if (a > 2 * Math.PI) a = a - (float)Math.PI * 2;
                    s.setMoveAngle(a);
                    s.setDisplayAngle(a);
                    if (ticks % 20 == 0) s.setMoveSpeed(1 + (random.Next(10) / 20.0f));
                    s.moveByAngleSpeed(true);
                    //s.setColor(Color.White);

                }
                this.AvoidObstacles(s);
            }
        }
    }
}
